Release 10.1A: OpenEdge Development:
Progress Dynamics Basic Development


Data objects page

Settings for SDOs are defined on the Data objects page, shown in Figure 5–4.

Figure 5–4: The Data objects page of the Object Generator

Above the DataObject and DataLogic Procedure frames is a field to select the root folder, as described in Table 5–2.

Table 5–2: Data objects page general fields
Option
Description
Root Folder
This prefix is the first part of the physical disk location where files will be stored. The Relative Path is the second part.
Create Folder if missing
This check box is used to create a physical folder on disk if the one specified does not exist.

The settings are described in Table 5–3.

Table 5–3: Settings for data objects
Option
Description
Object Type
DynSDO is the only type listed.
Product Module
The product module where the data objects will be generated is selected from this combo box.
Relative Path
This suffix forms the second part of the physical location on disk where .i files will be stored. The Root Folder makes up the first part.
Name Suffix
The ending that is added to the entity mnemonic (dumpname) for each table to form a complete name for the SDO procedure. You can change this to something other than fullo if you like.
Field Sequence
Suppress All Validation
Follow Joins

Create new SDOs or use existing SDOs

As discussed earlier, to use existing SDOs you uncheck the Data objects check box. The reason for this choice is that you might want to make some changes to your SDOs after generating them, but before generating browsers and viewers based on them.

These are some of the ways in which you can edit your SDOs:

So as a first pass through your tables, you should generate data objects so that you can modify SDOs in the AppBuilder as needed.

Then, as a second pass through the objects, you can create browsers and viewers based on the modified SDOs. When you do this, the Table browser changes to display SDOs instead, as shown in Figure 5–5.

Figure 5–5: Object Generator showing existing SDOs

Now you can select one or more SDOs, check the Browsers and/or Viewers toggle boxes, and have those objects created.

Suppress All Validation

The Suppress All Validation toggle box is checked by default, and you should almost always leave it that way. If you uncheck it, then any field validation expressions defined in the schema will be compiled into the SDOs temp-table definition, and in turn into visual objects such as static viewers built from the SDO. If this happens, then validation logic involving CAN-FIND expressions or other code requiring a database lookup will fail at run time, because there is no local database connection. In fact, a static procedure requiring a database that is not connected will not even load without error in the client session. In addition, schema field validation code will not be available to any dynamic object, so it will not be executed reliably in any case.

Other kinds of schema field validation are best left out as well. The default behavior that is compiled into a frame field with validation on it is to block an attempted LEAVE event on the field until its value is correct. A user could trigger a LEAVE event by selecting a button, in addition to tabbing out of the field. This behavior would be inappropriate. In general, it is not good GUI design to force validation of a value in a field before entering something in another field. You can write schema field validation into the client-side proxy for the SDO so that it is executed when the user tries to have all updates accepted, but before the record goes back to the server. If certain fields need specific validation, you can write code for this in the custom super procedure for the object, if it is dynamic, or into the object itself if it is procedure-based.

Field Sequence

The Field Sequence radio set lets you choose whether the order of the fields in the SDO will be according to the Order defined in the schema for the table (the default) or in alphabetical order. You can modify the order in the SDO after it is created. The Display Fields order determines the order of fields in default visual objects.

Follow Joins

The Object Generator can create joins to other related tables automatically, if your database schema conforms to the Progress Dynamics conventions described in Chapter 2 "Database Design Principles in Progress Dynamics" and Chapter 4, " Preparing to Build Application Objects." This means you must meet the following conditions:

If these conditions are met and you set the Follow Joins toggle box checked on (default is off), then the Object Generator adds joins to other related tables to the SDO query and adds the Entity Description field for each other table to the field list. You can then add these fields to a browser or viewer for the SDO.

If your database does not allow the framework to determine the proper joins and related fields, you can add these other tables and fields yourself after the SDOs are generated, as described earlier.

DataLogic Procedure

The settings for the contents of this frame are described in Table 5–4.

Table 5–4: Settings for DataLogic procedure
Option
Description
Product Module
The product module where the DataLogic Procedure will be generated in is selected from this combo box.
Object Type
The object type is selected from this combo box, typically DLProc.
Relative Path
This suffix forms the second part of the physical location on disk where .p files will be stored. The Root Folder makes up the first part.
Name Suffix
The ending that is added to the Entity Mnemonic for each table to form a complete name for the Logic procedure. You can change this to something other than logcp if you like, but the .p extension has to remain the same.
Template

The procedure file that is used as the basis for generating the Logic procedure associated with the SDO. Again, you would not normally change this name; if you want to customize it, the same caveats apply as for the SDO template name.

SDO validation logic generation

The Object Generator creates a logic procedure for each SDO and puts some of the initial validation logic in place, based on what it can derive from the database schema. This can be a useful starting point for your SDO logic, which you can edit and extend as necessary. Chapter 11, "Building Advanced Business Logic in a Progress Dynamics Application," discusses writing code of this kind in more detail.

As an example, the logic procedure for the Customer SDO contains these three internal procedures that come from the Object Generator:

The validation based on setting controls what kind of logic gets generated:

RowObjectValidate

RowObjectValidate is the procedure executed on the client side of the application when a record is saved, but before it is sent back to the server. Validation that can be done without database lookups can be placed in this procedure. The isFieldBlank function checks whether a field is either blank or has the unknown value, as shown:

/*------------------------------------------------------------------------- 
 Purpose:   Procedure used to validate RowObject record client-side 
 Parameters: <none>  
-------------------------------------------------------------------------*/ 
 DEFINE VARIABLE cMessageList  AS CHARACTER  NO-UNDO. 
 DEFINE VARIABLE cValueList   AS CHARACTER  NO-UNDO. 
 IF isFieldBlank(b_Customer.Comments) THEN 
  ASSIGN cMessageList = cMessageList +  
   (IF NUM-ENTRIES(cMessageList,CHR(3)) > 0 THEN CHR(3) ELSE '':U) +  
     {aferrortxt.i 'AF' '1' 'Customer' 'Comments' "'Comments'"}. 
 IF isFieldBlank(b_Customer.Country) THEN 
  ASSIGN cMessageList = cMessageList +  
   (IF NUM-ENTRIES(cMessageList,CHR(3)) > 0 THEN CHR(3) ELSE '':U) +  
     {aferrortxt.i 'AF' '1' 'Customer' 'Country' "'Country'"}. 
/* Additional similar validation omitted. */ 
 ERROR-STATUS:ERROR = NO. 
 RETURN cMessageList. 
END PROCEDURE. 

Note: When executing this procedure, the saved record is available in a buffer with the SDOs principal table name preceded by b_. The procedure builds a message list (using a standard variable available to all such procedures) of any errors generated. The validation check is handled by the include file, aferrortxt.i, which takes a variety of possible include file parameters, as described in Chapter 11, " Building Advanced Business Logic in a Progress Dynamics Application." The framework accumulates any error messages so that it can return all errors to the user in one call.

The second validation procedure that Progress Dynamics generates handles new record creates and is intended to execute on the server side of the SDO. This procedure is createPreTransValidate, which means that this is a record CREATE validation that runs before the server-side update transaction begins. This example verifies that the CustNum value entered does not already exist in the database. Even though Progress would catch this error at the database level and report it (because there is a unique index on the CustNum field), it is very useful to catch these types of errors in application code before getting down to the default Progress error message generation. This way, you have control over the text of the error message (which will include an intelligible form of the table name, based on the Entity Short Description, etc.), and how it is handled, as shown:

/*------------------------------------------------------------------------ 
 Purpose:   Procedure used to validate records server-side before the  
        transaction scope upon create 
 Parameters: <none> 
------------------------------------------------------------------------*/ 
 DEFINE VARIABLE cMessageList  AS CHARACTER  NO-UNDO. 
 DEFINE VARIABLE cValueList   AS CHARACTER  NO-UNDO. 
 IF CAN-FIND(FIRST Customer  
       WHERE Customer.CustNum = b_Customer.CustNum) THEN 
 DO: 
   ASSIGN 
    cValueList  = STRING(b_Customer.CustNum) 
    cMessageList = cMessageList +  
     (IF NUM-ENTRIES(cMessageList,CHR(3)) > 0 THEN CHR(3) ELSE '':U) +  
     {aferrortxt.i 'AF' '8' 'Customer' '' "'CustNum, '" cValueList }. 
 END. 
 ERROR-STATUS:ERROR = NO. 
 RETURN cMessageList. 
END PROCEDURE. 

The third example is the procedure writePreTransValidate, which executes on the server side for all database write operations of new or existing records. This variation on the previous logic for CREATE checks whether this is a write of a new record by using a standard function isCreate(), and if not, verifies that the CustNum value in the record does not match the CustNum of some other existing database record.

Here is the code:

/*------------------------------------------------------------------------ 
 Purpose:   Procedure used to validate records server-side before the  
        transaction scope upon write 
 Parameters: <none> 
------------------------------------------------------------------------*/ 
 DEFINE VARIABLE cMessageList  AS CHARACTER  NO-UNDO. 
 DEFINE VARIABLE cValueList   AS CHARACTER  NO-UNDO. 
 IF NOT isCreate() AND CAN-FIND(FIRST Customer  
       WHERE Customer.CustNum = b_Customer.CustNum 
        AND ROWID(Customer) <> TO-ROWID(ENTRY(1,b_Customer.RowIDent)))   
 THEN DO: 
   ASSIGN cValueList  = STRING(b_Customer.CustNum) 
      cMessageList = cMessageList +  
      (IF NUM-ENTRIES(cMessageList,CHR(3)) > 0 THEN CHR(3) ELSE '':U) +  
       {aferrortxt.i 'AF' '8' 'Customer' '' "'CustNum, '" cValueList }. 
 END. 
 ERROR-STATUS:ERROR = NO. 
 RETURN cMessageList. 
END PROCEDURE. 


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095